home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / DEMOS / underwater / TEXLOAD.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  6.2 KB  |  254 lines

  1.  
  2. /* texture.c - by David Blythe, SGI */
  3.  
  4. /* texload is a simplistic routine for reading an SGI .rgb image file. */
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h> 
  8. #include <string.h>
  9.  
  10. #include "texload.h"
  11.  
  12. typedef struct _ImageRec {
  13.     unsigned short imagic;
  14.     unsigned short type;
  15.     unsigned short dim;
  16.     unsigned short xsize, ysize, zsize;
  17.     unsigned int min, max;
  18.     unsigned int wasteBytes;
  19.     char name[80];
  20.     unsigned long colorMap;
  21.     FILE *file;
  22.     unsigned char *tmp;
  23.     unsigned long rleEnd;
  24.     unsigned int *rowStart;
  25.     int *rowSize;
  26. } ImageRec;
  27.  
  28. void
  29. rgbtorgb(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *l,int n) {
  30.     while(n--) {
  31.         l[0] = r[0];
  32.         l[1] = g[0];
  33.         l[2] = b[0];
  34.         l += 3; r++; g++; b++;
  35.     }
  36. }
  37.  
  38. static void
  39. ConvertShort(unsigned short *array, unsigned int length) {
  40.     unsigned short b1, b2;
  41.     unsigned char *ptr;
  42.  
  43.     ptr = (unsigned char *)array;
  44.     while (length--) {
  45.         b1 = *ptr++;
  46.         b2 = *ptr++;
  47.         *array++ = (b1 << 8) | (b2);
  48.     }
  49. }
  50.  
  51. static void
  52. ConvertUint(unsigned *array, unsigned int length) {
  53.     unsigned int b1, b2, b3, b4;
  54.     unsigned char *ptr;
  55.  
  56.     ptr = (unsigned char *)array;
  57.     while (length--) {
  58.         b1 = *ptr++;
  59.         b2 = *ptr++;
  60.         b3 = *ptr++;
  61.         b4 = *ptr++;
  62.         *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
  63.     }
  64. }
  65.  
  66. static ImageRec *ImageOpen(char *fileName)
  67. {
  68.     union {
  69.         int testWord;
  70.         char testByte[4];
  71.     } endianTest;
  72.     ImageRec *image;
  73.     int swapFlag;
  74.     int x;
  75.  
  76.     endianTest.testWord = 1;
  77.     if (endianTest.testByte[0] == 1) {
  78.         swapFlag = 1;
  79.     } else {
  80.         swapFlag = 0;
  81.     }
  82.  
  83.     image = (ImageRec *)malloc(sizeof(ImageRec));
  84.     if (image == NULL) {
  85.         fprintf(stderr, "Out of memory!\n");
  86.         exit(1);
  87.     }
  88.     if ((image->file = fopen(fileName, "rb")) == NULL) {
  89.     return NULL;
  90.     }
  91.  
  92.     fread(image, 1, 12, image->file);
  93.  
  94.     if (swapFlag) {
  95.         ConvertShort(&image->imagic, 6);
  96.     }
  97.  
  98.     image->tmp = (unsigned char *)malloc(image->xsize*256);
  99.     if (image->tmp == NULL) {
  100.         fprintf(stderr, "\nOut of memory!\n");
  101.         exit(1);
  102.     }
  103.  
  104.     if ((image->type & 0xFF00) == 0x0100) {
  105.         x = image->ysize * image->zsize * (int) sizeof(unsigned);
  106.         image->rowStart = (unsigned *)malloc(x);
  107.         image->rowSize = (int *)malloc(x);
  108.         if (image->rowStart == NULL || image->rowSize == NULL) {
  109.             fprintf(stderr, "\nOut of memory!\n");
  110.             exit(1);
  111.         }
  112.         image->rleEnd = 512 + (2 * x);
  113.         fseek(image->file, 512, SEEK_SET);
  114.         fread(image->rowStart, 1, x, image->file);
  115.         fread(image->rowSize, 1, x, image->file);
  116.         if (swapFlag) {
  117.             ConvertUint(image->rowStart, x/(int) sizeof(unsigned));
  118.             ConvertUint((unsigned *)image->rowSize, x/(int) sizeof(int));
  119.         }
  120.     }
  121.     return image;
  122. }
  123.  
  124. static void
  125. ImageClose(ImageRec *image) {
  126.     fclose(image->file);
  127.     free(image->tmp);
  128.     free(image);
  129. }
  130.  
  131. static void
  132. ImageGetRow(ImageRec *image, unsigned char *buf, int y, int z) {
  133.     unsigned char *iPtr, *oPtr, pixel;
  134.     int count;
  135.  
  136.     if ((image->type & 0xFF00) == 0x0100) {
  137.         fseek(image->file, (long) image->rowStart[y+z*image->ysize], SEEK_SET);
  138.         fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize],
  139.               image->file);
  140.  
  141.         iPtr = image->tmp;
  142.         oPtr = buf;
  143.         for (;;) {
  144.             pixel = *iPtr++;
  145.             count = (int)(pixel & 0x7F);
  146.             if (!count) {
  147.                 return;
  148.             }
  149.             if (pixel & 0x80) {
  150.                 while (count--) {
  151.                     *oPtr++ = *iPtr++;
  152.                 }
  153.             } else {
  154.                 pixel = *iPtr++;
  155.                 while (count--) {
  156.                     *oPtr++ = pixel;
  157.                 }
  158.             }
  159.         }
  160.     } else {
  161.         fseek(image->file, 512+(y*image->xsize)+(z*image->xsize*image->ysize),
  162.               SEEK_SET);
  163.         fread(buf, 1, image->xsize, image->file);
  164.     }
  165. }
  166.  
  167. GLubyte *
  168. read_alpha_texture(char *name, int *width, int *height)
  169. {
  170.     unsigned char *base, *lptr;
  171.     ImageRec *image;
  172.     int y;
  173.  
  174.     image = ImageOpen(name);
  175.     if(!image) {
  176.         return NULL;
  177.     }
  178.  
  179.     (*width)=image->xsize;
  180.     (*height)=image->ysize;
  181.     if (image->zsize != 1) {
  182.       ImageClose(image);
  183.       return NULL;
  184.     }
  185.  
  186.     base = (unsigned char *)malloc(image->xsize*image->ysize*sizeof(unsigned char));
  187.     lptr = base;
  188.     for(y=0; y<image->ysize; y++) {
  189.         ImageGetRow(image,lptr,y,0);
  190.         lptr += image->xsize;
  191.     }
  192.     ImageClose(image);
  193.  
  194.     return (unsigned char *) base;
  195. }
  196.  
  197. GLubyte *
  198. read_rgb_texture(char *name, int *width, int *height)
  199. {
  200.     unsigned char *base, *ptr;
  201.     unsigned char *rbuf, *gbuf, *bbuf, *abuf;
  202.     ImageRec *image;
  203.     int y;
  204.  
  205.     image = ImageOpen(name);
  206.     
  207.     if(!image)
  208.         return NULL;
  209.     (*width)=image->xsize;
  210.     (*height)=image->ysize;
  211.     if (image->zsize != 3 && image->zsize != 4) {
  212.       ImageClose(image);
  213.       return NULL;
  214.     }
  215.  
  216.     base = (unsigned char*)malloc(image->xsize*image->ysize*sizeof(unsigned int)*3);
  217.     rbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
  218.     gbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
  219.     bbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
  220.     abuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
  221.     if(!base || !rbuf || !gbuf || !bbuf || !abuf) {
  222.       if (base) free(base);
  223.       if (rbuf) free(rbuf);
  224.       if (gbuf) free(gbuf);
  225.       if (bbuf) free(bbuf);
  226.       if (abuf) free(abuf);
  227.       return NULL;
  228.     }
  229.     ptr = base;
  230.     for(y=0; y<image->ysize; y++) {
  231.         if(image->zsize == 4) {
  232.             ImageGetRow(image,rbuf,y,0);
  233.             ImageGetRow(image,gbuf,y,1);
  234.             ImageGetRow(image,bbuf,y,2);
  235.             ImageGetRow(image,abuf,y,3);  /* Discard. */
  236.             rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize);
  237.             ptr += (image->xsize * 3);
  238.         } else {
  239.             ImageGetRow(image,rbuf,y,0);
  240.             ImageGetRow(image,gbuf,y,1);
  241.             ImageGetRow(image,bbuf,y,2);
  242.             rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize);
  243.             ptr += (image->xsize * 3);
  244.         }
  245.     }
  246.     ImageClose(image);
  247.     free(rbuf);
  248.     free(gbuf);
  249.     free(bbuf);
  250.     free(abuf);
  251.  
  252.     return (GLubyte *) base;
  253. }
  254.